package com.futuristik.arkitek;

import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.FPSLogger;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer;
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer10;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.World;
import com.futuristik.objects.ArkitekObject;

public class ArkitekRenderer {
	World world;
	Map map;
	
	SpriteBatch batch = new SpriteBatch(100);
	ImmediateModeRenderer renderer = new ImmediateModeRenderer10();
	
	Mesh backgroundMesh;

	/*
	 * This will be replaced by our own renderer!
	 */
	//Box2DDebugRenderer debugRenderer = new Box2DDebugRenderer(true, false, false);
	
	FPSLogger fps = new FPSLogger();
	
	float stateTime = 0;
	
	public Character player;
	
	OrthographicCamera cam;
	
	public ArkitekRenderer(World w, OrthographicCamera c, Map m) {
		world = w;
		cam = c;
		map = m;
		
		backgroundMesh = new Mesh(true, 4, 4, new VertexAttribute(Usage.Position, 3, "a_position"), 
				new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));
		
		
		float worldHalfWidth = map.width/2f;
		float worldHalfHeight = map.height/2f;
		Vector2 center = new Vector2(0, 0);
		
		backgroundMesh.setVertices(verticesForUnscaledTexture(map.backgroundTexture, new float[] {
					center.x - worldHalfWidth, center.y - worldHalfHeight,
					center.x + worldHalfWidth, center.y - worldHalfHeight,
					center.x - worldHalfWidth, center.y + worldHalfHeight,
					center.x + worldHalfWidth, center.y + worldHalfHeight}));
				
		backgroundMesh.setIndices(new short[] { 0, 1, 2, 3 });
	}
	
	public void render (List<ArkitekObject> arr, float deltaTime) {		
		cam.update();
        cam.apply(Gdx.gl10);

        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        Gdx.graphics.getGL10().glEnable(GL10.GL_TEXTURE_2D);

        map.backgroundTexture.bind();
        backgroundMesh.render(GL10.GL_TRIANGLE_STRIP, 0, 4);
        
        //batch.draw(backgroundSprite, -32, -16, 0, 0, 64, 32, 1, 1, 0);

        batch.setProjectionMatrix(cam.combined);
        batch.enableBlending();
        batch.begin();
		
		for(ArkitekObject obj : arr){
			obj.render(batch);
		}
		
		
		batch.end();

        //debugRenderer.render(world, cam.combined);
		/*
		 * Here the objects in the Arkitek world will be rendered, etc.
		 * 
		Iterator<Body> bodies = world.getBodies();
		while(bodies.hasNext()){
			Body temp = bodies.next();
			
			System.out.println(temp.getUserData());
		}
		System.exit(1);
		
		 */
		
		
		//fps.log();
	}
	
	public void dispose(){
		batch.dispose();
	}
	
	//UTILITY
	
	 protected float[] verticesForUnscaledTexture(Texture texture, float[] vertices) {

	      float[] result = new float[5 * vertices.length / 2];

	      float u = ((float) Gdx.graphics.getWidth()) / texture.getWidth()/ 24;
	      float v = ((float) Gdx.graphics.getHeight()) / texture.getHeight()/ 16;

	      for (int i = 0; i < vertices.length / 2; i++) {

	         result[5 * i] = vertices[2 * i];
	         result[5 * i + 1] = vertices[2 * i + 1];
	         result[5 * i + 2] = 0;
	         result[5 * i + 3] = u * vertices[2 * i] ;
	         result[5 * i + 4] = -v * vertices[2 * i + 1] ;

	      }
	      return result;

	   }
}

